/*
* Copyright © Shanghai Awinic Technology Co., Ltd. 2020-2020. All rights reserved.
* Description: SYS driver related library function files.
* Date： 20201126
* Awinic_Version： aw_soc_driver_v1.0.0
*/
#include "compile_option.h"
#ifdef AW_86802

#include "aw8680x_global.h"

AW_S32 g_lock_cnt = 0;

#define INT_VECTOR_SIZE (30)
#define RAM_VECTOR_ADDR (0x20003D00)

RET_STATUS_E aw_set_vertor_to_ram(void)
{
 AW_U32 *p_int_vector_des = AW_NULL;
 AW_U32 *p_int_vector_sor = AW_NULL;

 p_int_vector_des = ((AW_U32 *)RAM_VECTOR_ADDR);
 p_int_vector_sor = ((AW_U32 *)FLASH_BASE);

 if((p_int_vector_des == AW_NULL) || (p_int_vector_sor == AW_NULL)) {
  return RET_ERROR;
 }

 memcpy(p_int_vector_des, p_int_vector_sor, (INT_VECTOR_SIZE) * sizeof(AW_U32));
 SCB->VTOR = ((AW_U32) RAM_VECTOR_ADDR);
 return RET_OK;
}

/**
  * @brief  Unlock register function
  * @param  None
  * @retval None
  */
void system_init(void)
{
  SYS->WR_PROT_KEY = PROTECT_FKEY1;
  SYS->WR_PROT_KEY = PROTECT_FKEY2;
  SYS->WR_PROT_KEY = PROTECT_FKEY3;
  SYS->WR_PROT_KEY = PROTECT_FKEY4;

	protect_unlock();
	CLK->CFG_EN |= CFG_LOSC_EN | CFG_EOSC_EN | CFG_BIAS_EN;
	CLK->HOSC_EN |= CFG_HOSC_EN;
	CLK->HOSC_MOD &= CFG_HOSC_24M_MOD;
	protect_lock();

  aw_set_vertor_to_ram();
}

/**
  * @brief  Unlock register function
  * @param  None
  * @retval AW library status
  */
#ifndef AWINIC_IAR
RET_STATUS_E protect_unlock(void)
#else
__ramfunc RET_STATUS_E protect_unlock(void)
#endif
{
	// if (g_lock_cnt == 0) {
	// 	SYS->WR_PROT_KEY = PROTECT_FKEY1;
	// 	SYS->WR_PROT_KEY = PROTECT_FKEY2;
	// 	SYS->WR_PROT_KEY = PROTECT_FKEY3;
	// 	SYS->WR_PROT_KEY = PROTECT_FKEY4;
	// }
	// g_lock_cnt++;
	// if ((SYS->SYS_WR_PROT & PROTECT_LOCK) == PROTECT_UNLOCK) {
	// 	return RET_OK;
	// } else {
	// 	return RET_ERROR;
	// }
  return RET_OK;
}

/**
  * @brief  Lock register function
  * @param  None
  * @retval AW library status
  */
#ifndef AWINIC_IAR
RET_STATUS_E protect_lock(void)
#else
__ramfunc RET_STATUS_E protect_lock(void)
#endif
{
	// g_lock_cnt--;
	// if (g_lock_cnt == 0) {
	// 	SYS->WR_PROT_KEY = PROTECT_FKEY0;
	// 	SYS->WR_PROT_KEY = PROTECT_FKEY0;
	// 	SYS->WR_PROT_KEY = PROTECT_FKEY0;
	// 	SYS->WR_PROT_KEY = PROTECT_FKEY0;
	// }

	// if ((SYS->SYS_WR_PROT & PROTECT_LOCK) == PROTECT_LOCK) {
	// 	return RET_OK;
	// }else {
	// 	return RET_ERROR;
	// }
  return RET_OK;
}

/**
  * @brief  I2C clk initialization function
  * @param  None
  * @retval None
  */
void i2c_clk_init(void)
{
	protect_unlock();
	CLK->I2C0_CLK_EN |= CFG_CLK_EN;
	protect_lock();
}

/**
  * @brief  I2C clk initialization function
  * @param  None
  * @retval None
  */
void i2c_close_clk(void)
{
	protect_unlock();
	CLK->I2C0_CLK_EN &= CFG_CLK_DIS;
	protect_lock();
}

/**
  * @brief  UART clk initialization function
  * @param  None
  * @retval None
  */
void uart_clk_init(void)
{
	CLK->UART_CLK_EN |= CFG_CLK_EN;
}

/**
  * @brief  FLASH clk initialization function
  * @param  None
  * @retval None
  */
void flash_clk_init(void)
{
	protect_unlock();
	CLK->ISP_CLK_EN |= CFG_CLK_EN;
	protect_lock();
}

/**
  * @brief  TIMER0 clk initialization function
  * @param  None
  * @retval None
  */
void timer0_clk_init(void)
{
	CLK->TMR0_CLK_EN |= CFG_CLK_EN;
}

/**
  * @brief  TIMER1 clk initialization function
  * @param  None
  * @retval None
  */
void timer1_clk_init(void)
{
	CLK->TMR1_CLK_EN |= CFG_CLK_EN;
}

/**
  * @brief  GPIO clk initialization function
  * @param  None
  * @retval None
  */
void gpio_clk_init(void)
{
	CLK->GPIO_CLK_EN |= CFG_CLK_EN;
}

/**
  * @brief  adc clk initialization function
  * @param  None
  * @retval None
  */
void adc_clk_init(AW_U32 adc_clkdiv)
{
	protect_unlock();
	/* system clock frequeny /frequency divided coefficient/40.
	for example : 24M/6/40=100K sps */
	CLK->ADC_CLK_DDIV = adc_clkdiv; // adc clk frequency configuration.
	CLK->ADC_CLK_EN |= CFG_CLK_EN;
	protect_lock();
}

/**
  * @brief  afe clk initialization function
  * @param  None
  * @retval None
  */
void afe_clk_init(void)
{
	CLK->AFE_CLK_EN |= CFG_CLK_EN;
}

/**
  * @brief  wdt0 clk initialization function
  * @param  None
  * @retval None
  */
void wdt0_clk_init(void)
{
	protect_unlock();
	CLK->WDT0_CLK_EN |= CFG_CLK_EN;
	protect_lock();
}

/**
  * @brief  wdt1 clk initialization function
  * @param  None
  * @retval None
  */
void wdt1_clk_init(void)
{
	protect_unlock();
	CLK->WDT1_CLK_EN |= CFG_CLK_EN;
	protect_lock();
}

/**
  * @brief  wdt1 clk initialization function
  * @param  None
  * @retval None
  */
void crc_clk_init(void)
{
	protect_unlock();
	CLK->CRC_CLK_EN |= CFG_CLK_EN;
	protect_lock();
}

/**
 * @brief   HDIV clk initialization function
  * @param  None
  * @retval None
  */
void hdiv_clk_init(void)
{
	protect_unlock();
	CLK->HDIV_CLK_EN |= CFG_HDIV_EN;
	protect_lock();
}

/**
  * @brief  I2C IO mode configuration function
  * @param  None
  * @retval None
  */
void i2c_pmux_init(void)
{
	protect_unlock();
	SYS->PA_MFC_MUX &= I2C_PMUX_MODE;
	protect_lock();
}

/**
  * @brief  UART IO mode configuration function
  * @param  None
  * @retval None
  */
void uart_pmux_init(AW_U8 gpio_pin_rx, AW_U8 gpio_pin_tx)
{
	protect_unlock();
	if (gpio_pin_rx == RX_GPIO_10) {
		SYS->PA_MFC_MUX |= 0x03 << gpio_pin_rx;
		SYS->PA_MFC_MUX &= ~(0x01 << gpio_pin_rx);
	} else if (gpio_pin_rx == RX_GPIO_13) {
		SYS->PA_MFC_MUX |= 0x03 << gpio_pin_rx;
		SYS->PA_MFC_MUX &= ~(0x02 << gpio_pin_rx);
	}
	if (gpio_pin_tx == TX_GPIO_11) {
		SYS->PA_MFC_MUX |= 0x03<< gpio_pin_tx;
		SYS->PA_MFC_MUX &= ~(0x01 << gpio_pin_tx);
	} else if (gpio_pin_tx == TX_GPIO_12) {
		SYS->PA_MFC_MUX |= 0x03<< gpio_pin_tx;
		SYS->PA_MFC_MUX &= ~(0x02 << gpio_pin_tx);
	}
	protect_lock();
}

/**
  * @brief  GPIO IO mode configuration function
  * @param  pin_mux_pa
  * @retval None
  */
void gpio_pmux_init(AW_U32 pin_mux_pa)
{
	protect_unlock();
	SYS->PA_MFC_MUX |= pin_mux_pa;
	protect_lock();
}

/**
  * @brief  GPIO IO open drain output configuration function
  * @param  gpio_pin
  * @retval None
  */
void gpio_od_config_en(AW_U32 gpio_pin)
{
	protect_unlock();
	SYS->PA_IN_EN |= GPIO_OD_IN_FLAG; // OD_OUT and OD_IN
	SYS->PA_OD_EN |= gpio_pin; // OD
	protect_lock();
}

/**
  * @brief  GPIO IO Push-pull output configuration function
  * @param  gpio_pin
  * @retval None
  */
void gpio_pa_config_en(AW_U32 gpio_pin)
{
	protect_unlock();
	SYS->PA_IN_EN &= ~(gpio_pin & GPIO_PA_OUT_FLAG); // OUTPUT
	SYS->PA_OD_EN &= ~(gpio_pin & GPIO_PA_OUT_FLAG); // Push_pull
	protect_lock();
}

/**
  * @brief  GPIO fast speed mode configuration function
  * @param  gpio_pin
  * @retval None
  */
void gpio_speed_fast(AW_U32 gpio_pin)
{
	protect_unlock();
	SYS->PA_FAST |= gpio_pin;
	SYS->PA_ADJ_OD |= gpio_pin;
	SYS->PA_SR_CTRL1 |= gpio_pin;
	SYS->PA_SR_CTRL2 |= gpio_pin;
	protect_lock();
}

/**
  * @brief  GPIO slow speed mode configuration function
  * @param  gpio_pin
  * @retval None
  */
void gpio_speed_slow(AW_U32 gpio_pin)
{
	protect_unlock();
	SYS->PA_FAST &= gpio_pin;
	SYS->PA_ADJ_OD &= gpio_pin;
	SYS->PA_SR_CTRL1 &= gpio_pin;
	SYS->PA_SR_CTRL2 &= gpio_pin;
	protect_lock();
}

/**
  * @brief  Allow WDT0 auto reset function
  * @param  None
  * @retval None
  */
void wdt0_rst_en(void)
{
	RST->WDT_RSTN |= WDT0_RST_EN;
}

/**
  * @brief  Allow WDT1 auto reset function
  * @param  None
  * @retval None
  */
void wdt1_rst_en(void)
{
	RST->WDT_RSTN |= WDT1_RST_EN;
}

/**
  * @brief  Set interrupt sequence number offset address function
  * @param  None
  * @retval None
  */
void system_set_vtor(AW_U32 vtor_data)
{
	SCB->VTOR = vtor_data;
}

/**
  * @brief  Disanbling i2c function
  * @param  None
  * @retval None
  */
static void i2c_clean_enable(void)
{
	I2C0->ENABLE = CLEAN_DATA; //Disanbling i2c
}

/**
  * @brief  Close i2c device function
  * @param  None
  * @retval None
  */
void i2c_close_device(void)
{
	i2c_clean_enable();
	i2c_close_clk();
}
#endif
